package agents

import (
	"context"
	"errors"
	"k8sops/pkg/client"
	"log"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)

func NamespaceCopy(sourceNamespace, targetNamespace string) (err error) {
	k := client.K8sClientSet{}
	c, err := k.GetClientset()
	if err != nil {
		log.Fatal(err.Error())
		return
	}
	if !NamespaceExist(c, sourceNamespace) {
		return errors.New("source namespace not exist")
	}
	if !NamespaceExist(c, targetNamespace) {
		return errors.New("target namespace not exist")
	}

	// copy deployments
	err = copyDeployments(c, sourceNamespace, targetNamespace)
	if err != nil {
		log.Fatal(err.Error())
		return
	}

	// copy statefulsets
	err = copyStatefulSets(c, sourceNamespace, targetNamespace)
	if err != nil {
		log.Fatal(err.Error())
		return
	}

	// copy configmaps
	err = copyConfigMaps(c, sourceNamespace, targetNamespace)
	if err != nil {
		log.Fatal(err.Error())
		return
	}

	return
}

func copyDeployments(c *kubernetes.Clientset, sourceNamespace, targetNamespace string) (err error) {
	deployments, err := c.AppsV1().Deployments(sourceNamespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
		return
	}
	for _, deployment := range deployments.Items {
		deployment.ResourceVersion = ""
		deployment.Namespace = targetNamespace
		_, err = c.AppsV1().Deployments(targetNamespace).Create(context.TODO(), &deployment, metav1.CreateOptions{})
		if err != nil {
			log.Fatal(err.Error())
			return
		}
	}
	return
}

func copyStatefulSets(c *kubernetes.Clientset, sourceNamespace, targetNamespace string) (err error) {
	statefulSets, err := c.AppsV1().StatefulSets(sourceNamespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
		return
	}
	for _, statefulSet := range statefulSets.Items {
		statefulSet.ResourceVersion = ""
		statefulSet.Namespace = targetNamespace
		_, err = c.AppsV1().StatefulSets(targetNamespace).Create(context.TODO(), &statefulSet, metav1.CreateOptions{})
		if err != nil {
			log.Fatal(err.Error())
			return
		}
	}
	return
}

func copyConfigMaps(c *kubernetes.Clientset, sourceNamespace, targetNamespace string) (err error) {
	configMaps, err := c.CoreV1().ConfigMaps(sourceNamespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
		return
	}
	for _, configMap := range configMaps.Items {
		if configMap.Name == "kube-root-ca.crt" {
			continue
		}
		configMap.ResourceVersion = ""
		configMap.Namespace = targetNamespace
		_, err = c.CoreV1().ConfigMaps(targetNamespace).Create(context.TODO(), &configMap, metav1.CreateOptions{})
		if err != nil {
			log.Fatal(err.Error())
			return
		}
	}
	return
}
